package com.cn.gmall.activity.controller;

import com.cn.gmall.activity.cache.CacheHelper;
import com.cn.gmall.activity.service.SeckillGoodsService;
import com.cn.gmall.common.constant.RedisConst;
import com.cn.gmall.common.mqconst.MqConst;
import com.cn.gmall.common.result.Result;
import com.cn.gmall.common.result.ResultCodeEnum;
import com.cn.gmall.common.service.RabbitService;
import com.cn.gmall.common.util.AuthContextHolder;
import com.cn.gmall.common.util.DateUtil;
import com.cn.gmall.common.util.MD5;
import com.cn.gmall.model.activity.OrderRecode;
import com.cn.gmall.model.activity.SeckillGoods;
import com.cn.gmall.model.activity.UserRecode;
import com.cn.gmall.model.order.OrderDetail;
import com.cn.gmall.model.order.OrderInfo;
import com.cn.gmall.model.user.UserAddress;
import com.cn.gmall.order.client.OrderFeignClient;
import com.cn.gmall.user.client.UserFeignClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.integration.annotation.Router;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.xml.crypto.Data;
import java.util.*;

@RestController
@RequestMapping("/api/activity/seckill")
public class SeckillApiController {
    @Resource
    private SeckillGoodsService seckillGoodsService;
    @Resource
    private RabbitService rabbitService;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private UserFeignClient userFeignClient;
    @Resource
    private OrderFeignClient orderFeignClient;

    /**
     * 秒杀下单 准备调用service-order 的方法 并且支付钱
     * api/activity/seckill/auth/submitOrder
     *
     * @return
     */
    @PostMapping("/auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfo orderInfo, HttpServletRequest request) {



        //获取userId
        String userId = AuthContextHolder.getUserId(request);
        orderInfo.setUserId(Long.parseLong(userId));
        //调用service-order 返回生成的订单Id
        Long orderId = orderFeignClient.submitOrderReturnId(orderInfo);
        //判断
        if (orderId != null) {
            //保存用户秒订单
            redisTemplate.opsForHash().put(RedisConst.SECKILL_ORDERS_USERS, userId, orderId);

            //清除临时订单
            redisTemplate.opsForHash().delete(RedisConst.SECKILL_ORDERS, userId);

            return Result.ok(orderId);
        }

        return Result.fail();
    }


    /**
     * 秒杀确认页 -拿地址信息 ->生成订单详情
     * /api/activity/seckill/auth/trade
     *
     * @return
     */
    @GetMapping("/auth/trade")
    public Result<Map<String, Object>> trade(HttpServletRequest request) {
        Map<String, Object> resultMap = new HashMap<>();
        //获取用户id
        String userId = AuthContextHolder.getUserId(request);
        //查询秒杀的临时订单
        OrderRecode recode = (OrderRecode) redisTemplate.opsForHash().get(RedisConst.SECKILL_ORDERS, userId);
        //判断
        if (recode == null) {
            return Result.build(null, ResultCodeEnum.ILLEGAL_REQUEST);
        }

        //查询用户的地址列表
        List<UserAddress> addresses = userFeignClient.findUserAddressListByUserId(Long.parseLong(userId));
        resultMap.put("userAddressList", addresses);
        //转换成订单详情
        SeckillGoods seckillGoods = recode.getSeckillGoods();
        //定义接收的集合
        List<OrderDetail> orderDetailList = new ArrayList<>();
        //创建订单详情
        OrderDetail detail = new OrderDetail();
        detail.setSkuId(seckillGoods.getSkuId());
        detail.setSkuName(seckillGoods.getSkuName());
        detail.setImgUrl(seckillGoods.getSkuDefaultImg());
        detail.setOrderPrice(seckillGoods.getCostPrice());
        detail.setSkuNum(1);
        orderDetailList.add(detail);
        resultMap.put("detailArrayList", orderDetailList);

        //计算总金额
        resultMap.put("totalAmount", seckillGoods.getCostPrice());
        //数量
        resultMap.put("totalNum", "1");

        return Result.ok(resultMap);
    }


    /**
     * api/activity/seckill/auth/checkOrder/23
     * 轮询查询抢购结果
     *
     * @param skuId
     * @return
     */
    @GetMapping("/auth/checkOrder/{skuId}")
    public Result checkOrder(@PathVariable String skuId, HttpServletRequest request) {
        //获取userId
        String userId = AuthContextHolder.getUserId(request);
        return seckillGoodsService.checkOrder(skuId, userId);
    }


    /**** 根据用户和商品ID实现秒杀下单(进行资格等一个校验)
     * /api/activity/seckill/auth/seckillOrder/{skuId}
     *
     * @param skuId
     * @param request
     * @return
     */
    @PostMapping("/auth/seckillOrder/{skuId}")
    public Result seckillOrder(@PathVariable Long skuId,
                               HttpServletRequest request) {
        String userId = AuthContextHolder.getUserId(request);
        String skuIdStr = request.getParameter("skuIdStr");
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(skuIdStr)) {
//        非法请求
            return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
        }
//        ----------加密用userId + skuId--->--------------
        if (!skuIdStr.equals(MD5.encrypt(userId + skuId))) {
//        请求不合法
            return Result.build(null, ResultCodeEnum.SECKILL_ILLEGAL);
        }
//---------------本地缓存 查看是否能抢-------------
        String state = CacheHelper.get(skuId.toString());
        if ("1".equals(state)) {
//    用户记录(存用户id和 skuId 记录一下谁抢了什么)
            UserRecode userRecode = new UserRecode();
            userRecode.setUserId(userId);
            userRecode.setSkuId(skuId);
// -----------发消息到------用户抢单队列------
            rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_SECKILL_USER,
                    MqConst.ROUTING_SECKILL_USER,
                    userRecode);
            return Result.ok();
        }

        return Result.build(null, ResultCodeEnum.SECKILL_FINISH);
    }


    /*** /api/activity/seckill/auth/getSeckillSkuIdStr/{skuId}
     * 获取下单码(进入秒杀的资格)
     * @param skuId
     * @return
     */
    @GetMapping("/auth/getSeckillSkuIdStr/{skuId}")
    public Result getSeckillSkuIdStr(@PathVariable Long skuId, HttpServletRequest request) {

        String userId = AuthContextHolder.getUserId(request);
        if (StringUtils.isEmpty(userId)) {
            Result.fail().message("登录已过期,请重新登录");
        }
//        获取当前秒杀的商品对象
        SeckillGoods seckillGoods = seckillGoodsService.getSeckillGoodsBySkuId(skuId);
        if (!ObjectUtils.isEmpty(seckillGoods)) {
            Date curTime = new Date();
//            判断当前时间是否可以抢 DateUtil.dateCompare(t1,t2) t1<t2 -->true
            if (DateUtil.dateCompare(seckillGoods.getStartTime(), curTime) &&
                    DateUtil.dateCompare(curTime, seckillGoods.getEndTime())) {
//----------------生成一个单码 放在redis里面----只有在商品秒杀时间范围内，才能获取下单码，这样我们就有效控制了用户非法秒杀------------

                String encrypt = MD5.encrypt(userId + skuId); //加密用userId + skuId
                return Result.ok(encrypt);
            }
        }
        return Result.fail().message("未找到该商品,获取单码失败");
    }


    /***
     * 根据skuId获取数据(数据来源redis)
     * /api/activity/seckill/getSeckillGoods/{skuId}
     * @param skuId
     * @return
     */
    @GetMapping("/getSeckillGoods/{skuId}")
    public Result getSeckillGoodsBySkuId(@PathVariable Long skuId) {
        SeckillGoods seckillGoods = seckillGoodsService.getSeckillGoodsBySkuId(skuId);

        return Result.ok(seckillGoods);
    }


    /**
     * /api/activity/seckill/findAll
     * 查询秒杀列表数据
     *
     * @return
     */
    @GetMapping("/findAll")
    public Result findAll() {

        List<SeckillGoods> seckillGoods = seckillGoodsService.findAll();


        return Result.ok(seckillGoods);
    }
}
